package com.brillilab.service.core.method.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.brillilab.common.entity.PageVo;
import com.brillilab.dao.mapper.method.MethodMapper;
import com.brillilab.domain.enums.common.BoolEnum;
import com.brillilab.domain.enums.common.IsDeleteEnum;
import com.brillilab.domain.enums.method.MethodSourceEnum;
import com.brillilab.domain.pa.method.MethodListPa;
import com.brillilab.domain.po.method.Method;
import com.brillilab.domain.po.method.MethodType;
import com.brillilab.domain.vo.method.*;
import com.brillilab.domain.vo.user.UserInfoVo;
import com.brillilab.service.core.method.IMethodService;
import com.brillilab.service.core.method.IMethodTypeService;
import com.github.pagehelper.PageHelper;

import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wuzhiyu
 * @Title: MethodSericeImpl
 * @ProjectName brill_lab
 * @Description: TODO
 * @date 2019/2/2113:14
 */
@Service
@Transactional
public class MethodServiceImpl implements IMethodService {
    @Resource
    private MethodMapper methodMapper;
    @Resource
    private IMethodTypeService methodTypeService;

    @Override
    public boolean saveMethodAndUpdateInitId(Method method) {
        methodMapper.insert(method);
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.eq(Method::getId, method.getId());
        Method up = new Method();
        if (MethodSourceEnum.CREATE.getSourceType().equals(method.getFromType())) {
            up.setSourceMethodId(method.getId());
        }
        up.setInitMethodId(method.getId());
        methodMapper.update(up, query);
        method.setInitMethodId(method.getId());
        return true;
    }

    @Override
    public Method getById(Long id) {
        return methodMapper.selectById(id);
    }

    @Override
    public ReferMethodListItem getReferRecommondOneByThirdTypeId(Long thirdTypeId) {
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.eq(Method::getMethodTypeId, thirdTypeId);
        query.isNull(Method::getUserId);
        query.eq(Method::getIsDelete, BoolEnum.FALSE.getValue());
        query.orderByDesc(Method::getExportCount);
        List<Method> methods = methodMapper.selectList(query);
        if (!CollectionUtils.isEmpty(methods)) {
            ReferMethodListItem item = new ReferMethodListItem();
            item.setExportCount(methods.get(0).getExportCount());
            item.setId(methods.get(0).getId());
            item.setName(methods.get(0).getName());
            return item;
        }
        return null;
    }

    @Override
    public List<Method> getReferMethodListByTypeAndName(Long thirdTypeId, String name) {
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.eq(Method::getUserId, null);
        query.eq(Method::getIsDelete, BoolEnum.FALSE.getValue());
        if (thirdTypeId == null && StringUtils.isEmpty(name)) {
            query.eq(Method::getIsDelete, BoolEnum.FALSE.getValue());
        }
        if (thirdTypeId != null) {
            query.eq(Method::getMethodTypeId, thirdTypeId);
        }
        if (!StringUtils.isEmpty(name)) {
            query.like(Method::getName, name);
        }
        query.orderByDesc(Method::getExportCount);
        return methodMapper.selectList(query);
    }

    @Override
    public List<Method> listByNameAndUserId(String methodName, Long userId) {
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.eq(Method::getName, methodName);
        query.eq(Method::getUserId, userId);
        query.eq(Method::getIsDelete, BoolEnum.FALSE.getValue());
        return methodMapper.selectList(query);
    }

    @Override
    public List<Method> listByTypeIdAndUserId(Long thirdTypeId, Long userId) {
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.eq(Method::getUserId, userId);
        query.eq(Method::getMethodTypeId, thirdTypeId);
        query.eq(Method::getIsDelete, BoolEnum.FALSE.getValue());
        query.eq(Method::getCurrent, BoolEnum.TRUE.getValue());
        return methodMapper.selectList(query);
    }

    @Override
    public List<Method> listByIdList(List<Long> methodIdList, Long userId) {
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.in(Method::getId, methodIdList);
        if (userId != null) {
            query.eq(Method::getUserId, userId);
        }
        return methodMapper.selectList(query);
    }

    @Override
    public boolean save(Method method) {
        if (method.getCurrent() == 1 && method.getUserId() != null) {
            LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
            query.eq(Method::getInitMethodId, method.getInitMethodId());
            query.eq(Method::getUserId, method.getUserId());
            Method update = new Method();
            update.setCurrent(0);
            methodMapper.update(update, query);
        }
        methodMapper.insert(method);
        if (method.getSourceMethodId() == null) {
            Method up = new Method();
            up.setId(method.getId());
            up.setSourceMethodId(method.getId());
            methodMapper.updateById(up);
        }
        return true;
    }

    @Override
    public Integer getCurrentMaxVersion(Long initMethodId) {
        return methodMapper.getCurrentVersion(initMethodId);
    }

    @Override
    public List<Method> selectListByMethodTypeId(Long typeId, Long userId) {
        Assert.notNull(typeId, "参数缺失！");
        LambdaQueryWrapper<Method> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Method::getUserId, userId);
        wrapper.eq(Method::getMethodTypeId, typeId);
        wrapper.eq(Method::getIsDelete, IsDeleteEnum.NO.getValue());
        return methodMapper.selectList(wrapper);
    }

    @Override
    public List<Method> listByInitMethodId(Long initMethodId, Long userId) {
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.eq(Method::getInitMethodId, initMethodId);
        query.eq(Method::getUserId, userId);
        query.orderByDesc(Method::getVersion);
        query.eq(Method::getIsDelete, BoolEnum.FALSE.getValue());
        return methodMapper.selectList(query);
    }

    @Override
    public PageVo<Method> listPagedReferMethod(List<Long> thirdTypeIdList, String name, Integer pageIndex, Integer rows, boolean isKit) {
        PageHelper.startPage(pageIndex, rows);
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.isNull(Method::getUserId);
        query.eq(Method::getIsDelete, BoolEnum.FALSE.getValue());
        query.eq(Method::getCurrent, BoolEnum.TRUE.getValue());
        if (!CollectionUtils.isEmpty(thirdTypeIdList)) {
            query.in(Method::getMethodTypeId, thirdTypeIdList);
        }
        if (!StringUtils.isEmpty(name)) {
            query.like(Method::getName, name);
        }
        if (isKit){
            query.isNull(Method::getIsCommon);
        }
        query.orderByDesc(Method::getExportCount);
        List<Method> list = methodMapper.selectList(query);
        PageVo<Method> vo = new PageVo<>(list);
        return new PageVo<Method>(vo.getPageNum(), vo.getPageSize(), vo.getTotalRow(), list);
    }

    /**
     * @return boolean
     * @Description: TODO
     * @Params: [methodUpdate]
     * @author wuzhiyu
     * @date 2019/2/28 18:27
     */
    @Override
    public boolean update(MethodUpdate methodUpdate, UserInfoVo user) {
        Method method = methodMapper.selectById(methodUpdate.getId());
        Assert.isTrue(method != null && user.getId().equals(method.getUserId()), "数据不存在");
        Method newUpdate = new Method();
        BeanUtils.copyProperties(methodUpdate, newUpdate);
        return methodMapper.updateById(newUpdate) > 0;
    }

    @Override
    public Method getByInitMethodIdAndVersion(Long initMethodId, Integer version) {
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.eq(Method::getInitMethodId, initMethodId);
        query.eq(Method::getVersion, version);
        return methodMapper.selectOne(query);
    }

    @Override
    public List<Method> listSameSourceMethod(Long sourceMethodId, Long userId) {
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.eq(Method::getSourceMethodId, sourceMethodId);
        query.eq(Method::getUserId, userId);
        query.eq(Method::getIsDelete, BoolEnum.FALSE.getValue());
        query.eq(Method::getCurrent, BoolEnum.TRUE.getValue());
        return methodMapper.selectList(query);
    }

    /**
     * ######################## lijian #############################
     */
    @Override
    public ReferMethodStatisticsVo referMethodStatistics() {
        ReferMethodStatisticsVo vo = new ReferMethodStatisticsVo();
        //当前方法数量
        LambdaQueryWrapper<Method> query1 = new LambdaQueryWrapper<>();
        query1.isNull(Method::getUserId);
        query1.eq(Method::getCurrent, BoolEnum.TRUE.getValue());
        query1.eq(Method::getIsDelete, BoolEnum.FALSE.getValue());
        Integer currentCount = methodMapper.selectCount(query1);
        vo.setCurrentCount(currentCount);
        //今日上传数量
        LocalDateTime localDateTime = LocalDateTime.now();
        LocalDateTime minTime = localDateTime.with(LocalTime.MIN);
        LocalDateTime maxTime = localDateTime.with(LocalTime.MAX);

        LambdaQueryWrapper<Method> query2 = new LambdaQueryWrapper<>();
        query2.isNull(Method::getUserId);
        query2.eq(Method::getIsDelete, BoolEnum.FALSE.getValue());
        query2.ge(Method::getCreateTime, minTime);
        query2.le(Method::getCreateTime, maxTime);
        query1.eq(Method::getCurrent, BoolEnum.TRUE.getValue());
        Integer todayUploadCount = methodMapper.selectCount(query2);
        vo.setTodayUploadCount(todayUploadCount);

        //今日导出数量
        LambdaQueryWrapper<Method> query3 = new LambdaQueryWrapper<>();
        query3.eq(Method::getFromType, 0);
        query3.eq(Method::getCurrent, BoolEnum.TRUE.getValue());
        query3.ge(Method::getCreateTime, minTime);
        query3.le(Method::getCreateTime, maxTime);
        Integer todayExportCount = methodMapper.selectCount(query3);
        vo.setTodayExportCount(todayExportCount);

        //总导出数量
        LambdaQueryWrapper<Method> query4 = new LambdaQueryWrapper<>();
        query4.eq(Method::getFromType, 0);
        query4.eq(Method::getCurrent, BoolEnum.TRUE.getValue());
        Integer totalExportCount = methodMapper.selectCount(query4);
        vo.setTotalExportCount(totalExportCount);
        return vo;
    }

    @Override
    public List<MethodReferRecommendVo> getMethodReferRecommendList(Long userId, Long methodTypeId) {
        if (methodTypeId != null) {
           MethodTypeDetailVo detailVo = methodTypeService.getMethodFullNameByThirdId(methodTypeId);
            Assert.notNull(detailVo, "方法类型不存在！");
            Long firstId = detailVo.getFirstTypeId();
            String secondName = detailVo.getSecondTypeName();
            String methodTypeName = detailVo.getMethodTypeName();
            List<MethodReferRecommendVo> list = methodMapper.getMethodReferRecommendList(userId, firstId, secondName,
            		methodTypeName);
            if (CollectionUtils.isEmpty(list)) {
                list = methodMapper.getMethodReferRecommendList(userId, firstId, secondName, null);
                if (CollectionUtils.isEmpty(list)) {
                    list = methodMapper.getMethodReferRecommendList(userId, firstId, null, null);
                }
            }
            return list;
        }
        return methodMapper.getMethodReferRecommendList(userId, null, null, null);
    }

    @Override
    public PageVo<MethodListVo> getMethodList(MethodListPa pa) {
        Assert.isTrue(pa != null && pa.getUserId() != null, "缺少参数");
        PageHelper.startPage(pa.getPageNum(), pa.getPageSize());
        List<MethodListVo> voList = methodMapper.getMethodList(pa);
        return new PageVo<MethodListVo>(voList);
    }

    @Override
    public List<MethodContrastVo> getMethodContrastChartList(Long labId, List<Long> firstTypeIds) {
        List<MethodContrastVo> contrastVoList = new ArrayList<MethodContrastVo>();
        //归属到一级类型
        List<MethodType> firstMethodTypes = null;
        if (firstTypeIds != null) {
            firstMethodTypes = methodTypeService.listByIdList(firstTypeIds);
        } else {
            firstMethodTypes = methodTypeService.selectAllFirstMethodType();
        }
        for (MethodType firstType : firstMethodTypes) { //组装一级类型数据前端显示
            MethodContrastVo vo = new MethodContrastVo();
            vo.setFirstTypeId(firstType.getId());
            vo.setFirstTypeName(firstType.getName());
            contrastVoList.add(vo);
        }
        //获取所有符合的方法数据
        List<MethodContrastChartVo> chartList = methodMapper.getMethodChartList(labId, firstTypeIds);
        return getContrastVoList(contrastVoList, chartList, null, null);
    }

    @Override
    public MethodContrastChartListVo getMethodContrastChart(Long labId, Long firstTypeId, String secondTypeName,
                                                            String methodTypeName, Integer sortType, Integer sort) {
        //获取所有符合的方法数据
        List<MethodContrastChartVo> chartList = methodMapper.getMethodChartInfo(labId, firstTypeId, secondTypeName, methodTypeName);
        if (CollectionUtils.isEmpty(chartList)) {
            return null;
        }

        List<MethodContrastVo> contrastVoList = new ArrayList<MethodContrastVo>();
        MethodContrastVo vo = new MethodContrastVo();
        vo.setFirstTypeId(firstTypeId);
        contrastVoList.add(vo);
        contrastVoList = getContrastVoList(contrastVoList, chartList, sortType, sort);
        List<MethodContrastChartListVo> contrastList = contrastVoList.get(0).getContrastList();
        return contrastList.get(0);
    }

    private List<MethodContrastVo> getContrastVoList(List<MethodContrastVo> contrastVoList, List<MethodContrastChartVo> chartList, Integer sortType, Integer sort) {
        if (CollectionUtils.isEmpty(chartList)) {
            return contrastVoList;
        }
        // 方法分类
        Map<String, MethodContrastChartListVo> map = new HashMap<String, MethodContrastChartListVo>();
        for (MethodContrastChartVo chartVo : chartList) {
            String key = chartVo.getFirstTypeId() + chartVo.getSecondTypeName() + chartVo.getMethodTypeName();
            MethodContrastChartListVo chartListVo = map.get(key);
            if (chartListVo == null) {
                chartListVo = new MethodContrastChartListVo();
                chartListVo.setFirstTypeId(chartVo.getFirstTypeId());
                chartListVo.setFirstTypeName(chartVo.getFirstTypeName());
                chartListVo.setSecondTypeName(chartVo.getSecondTypeName());
                chartListVo.setMethodTypeName(chartVo.getMethodTypeName());

                chartListVo.setRecommendList(new ArrayList<MethodContrastChartVo>());
                chartListVo.setChartList(new ArrayList<MethodContrastChartVo>());
            }
            if (chartVo.getIsRecommend() == 1) {//推荐方法
                chartListVo.getRecommendList().add(chartVo);
            } else {//普通方法
                chartListVo.getChartList().add(chartVo);
            }
            map.put(key, chartListVo);
        }

        List<MethodContrastChartListVo> voList = new ArrayList<MethodContrastChartListVo>();
        for (MethodContrastChartListVo vo : map.values()) {

            //三级类型数据统计
            List<MethodContrastChartVo> allList = new ArrayList<MethodContrastChartVo>();
            allList.addAll(vo.getChartList());
            allList.addAll(vo.getRecommendList());
            int memberNum = allList.stream().collect(Collectors.groupingBy(MethodContrastChartVo::getLabMemberId)).size();
            vo.setMemberNum(memberNum);
            int totalExportCount = 0;
            for (MethodContrastChartVo chartVo : allList) {
                totalExportCount += chartVo.getExportCount();
            }
            vo.setTotalExportCount(totalExportCount);

            // 合并推荐方法数据
            List<MethodContrastChartVo> recommendMethodList = new ArrayList<MethodContrastChartVo>();
            List<MethodContrastChartVo> recommendList = vo.getRecommendList();
            if (recommendList.size() > 0) {
                // 推荐方法分组
                Map<Long, List<MethodContrastChartVo>> recommendMap = recommendList.stream().collect(Collectors.groupingBy(MethodContrastChartVo::getRecommendMethodId));
                int i = 1;
                for (List<MethodContrastChartVo> list : recommendMap.values()) {
                    MethodContrastChartVo recommend = null;
                    for (MethodContrastChartVo chartVo : list) {
                        if (recommend == null) {
                            recommend = chartVo;
                            recommend.setUserName("推荐方法" + i);
                            i++;
                        } else {
                            recommend.setSuccessCount(recommend.getSuccessCount() + chartVo.getSuccessCount());
                            recommend.setExportCount(recommend.getExportCount() + chartVo.getExportCount());
                        }
                    }
                    if (recommend.getExportCount() > 0 && recommend.getSuccessCount() > 0) {
                        BigDecimal successRate = new BigDecimal(recommend.getSuccessCount())
                                .divide(new BigDecimal(recommend.getExportCount()), 4, RoundingMode.HALF_UP);
                        recommend.setSuccessRate(successRate);
                    }
                    recommendMethodList.add(recommend);
                }
            }

            vo.getChartList().addAll(recommendMethodList);
            vo.setRecommendList(null);

            //sortType: 1-调用次（默认）,2-成功率,3-成员
            if (sortType != null && sortType == 2) {
                Collections.sort(vo.getChartList(), new Comparator<MethodContrastChartVo>() {
                    @Override
                    public int compare(MethodContrastChartVo o1, MethodContrastChartVo o2) {
                        if (sort != null && sort == 1) {
                            // 按成功率降序
                            return o2.getSuccessRate().compareTo(o1.getSuccessRate());
                        } else {
                            // 按成功率升序
                            return o1.getSuccessRate().compareTo(o2.getSuccessRate());
                        }
                    }
                });
            } else if (sortType != null && sortType == 3) {
                Collections.sort(vo.getChartList(), new Comparator<MethodContrastChartVo>() {
                    @Override
                    public int compare(MethodContrastChartVo o1, MethodContrastChartVo o2) {
                        if (sort != null && sort == 1) {
                            // 成员姓名降序
                            return o1.getUserName().compareTo(o2.getUserName());
                        } else {
                            // 成员姓名升序
                            return o2.getUserName().compareTo(o1.getUserName());
                        }
                    }
                });
            } else {
                Collections.sort(vo.getChartList(), new Comparator<MethodContrastChartVo>() {
                    @Override
                    public int compare(MethodContrastChartVo o1, MethodContrastChartVo o2) {
                        if (sort != null && sort == 1) {
                            // 按总调用次数降序
                            if(o1.getExportCount() > o2.getExportCount()) return -1;
                        	if(o1.getExportCount() < o2.getExportCount()) return 1;
                        	else return 0;
                        } else {
                            // 按总调用次数升序
                            if(o1.getExportCount() > o2.getExportCount()) return 1;
                        	if(o1.getExportCount() < o2.getExportCount()) return -1;
                        	else return 0;
                        }
                    }
                });
            }
            voList.add(vo);
        }

        Map<Long, List<MethodContrastChartListVo>> collect = voList.stream().collect(Collectors.groupingBy(MethodContrastChartListVo::getFirstTypeId));
        contrastVoList.forEach(vo -> {
            List<MethodContrastChartListVo> list = collect.get(vo.getFirstTypeId());
            if (!CollectionUtils.isEmpty(list)) {
                // 按总调方法数降序
                Collections.sort(list, new Comparator<MethodContrastChartListVo>() {
                    @Override
                    public int compare(MethodContrastChartListVo o1, MethodContrastChartListVo o2) {
                    	if(o1.getMethodNum() > o2.getMethodNum()) return -1;
                    	if(o1.getMethodNum() < o2.getMethodNum()) return 1;
                    	else return 0;
                    }
                });
                vo.setContrastList(list);
            }
        });
        return contrastVoList;
    }


    @Override
    public List<MethodMemberVo> getMethodMemberList(Long userId, Long labId, Integer state) {
        MethodMemberVo loginUser = null;
        List<MethodMemberVo> memberList = methodMapper.getMethodMemberList(labId, state);
        for (Iterator<MethodMemberVo> iterator = memberList.iterator(); iterator.hasNext(); ) {
            MethodMemberVo memberVo = iterator.next();
            if (memberVo.getUserId().equals(userId)) {
                loginUser = memberVo;
                iterator.remove();
                break;
            }
        }
        if (loginUser != null) {
            memberList.add(0, loginUser);
        }
        return methodMapper.getMethodMemberList(labId, state);
    }

    @Override
    public boolean delete(Long initMethodId, Long userId) {
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.eq(Method::getUserId, userId);
        query.eq(Method::getInitMethodId, initMethodId);
        Method update = new Method();
        update.setIsDelete(BoolEnum.TRUE.getValue());
        return methodMapper.update(update, query) > 0;
    }

    @Override
    public List<Method> listRecommendMethod(Long labId) {
        return methodMapper.listRecommendMethod(labId);
    }

	@Override
	@SuppressWarnings("unchecked")
    public List<Method> listByTypeIdListAndCurrent(List<Long> typeIdList, Long userId) {
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.in(Method::getMethodTypeId, typeIdList);
        query.eq(Method::getUserId, userId);
        query.eq(Method::getCurrent, BoolEnum.TRUE.getValue());
        query.eq(Method::getIsDelete, BoolEnum.FALSE.getValue());
        query.orderByDesc(Method::getSuccessCount);
        return methodMapper.selectList(query);
    }

    @Override
    public boolean saveMethodAndUpdateInitIdAndRecommentId(Method method) {
        methodMapper.insert(method);
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.eq(Method::getId, method.getId());
        Method up = new Method();
        up.setSourceMethodId(method.getId());
        up.setInitMethodId(method.getId());
        up.setRecommendMethodId(method.getId());
        methodMapper.update(up, query);
        return true;
    }

    @Override
    public boolean increaseExportCount(Long methodId) {
        return methodMapper.increaseExportCount(methodId) > 0;
    }

    @Override
    public List<Method> getByThirdTypeIdAndMethodNameAndUserId(Long thirdTypeId, String methodName, Long userId) {
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.eq(Method::getUserId, userId).eq(Method::getIsDelete, BoolEnum.FALSE.getValue()).eq(Method::getMethodTypeId, thirdTypeId).eq(Method::getName, methodName);
        return methodMapper.selectList(query);
    }

    @Override
    public List<Method> getSameTypeAndSameSourceMethod(String methodName,Long myThirdType, Long otherSourceMethodId, Long userId) {
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.eq(Method::getMethodTypeId, myThirdType);
        query.eq(Method::getSourceMethodId, otherSourceMethodId);
        query.eq(Method::getUserId, userId);
        query.eq(Method::getName, methodName);
        query.eq(Method::getIsDelete, BoolEnum.FALSE.getValue());
        query.eq(Method::getCurrent, BoolEnum.TRUE.getValue());
        return methodMapper.selectList(query);
    }

    @Override
    public List<Method> getMethodListByUserIdAndState(Long userId, BoolEnum isDelete,BoolEnum isCurrent,boolean hasCommonMethod) {
        return methodMapper.getMethodListByUserIdAndState(userId,isDelete,isCurrent,hasCommonMethod);
    }

    /**
     * ######################## lijian #############################
     */

    @Override
    public boolean updateById(Method method) {
        return methodMapper.updateById(method) == 1;
    }

    @Override
    public List<Method> selectListByIds(List<Long> methodIds) {
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.in(Method::getId, methodIds);
        return methodMapper.selectList(query);
    }

    @Override
    public List<Method> listByRecommendMethodId(Long recommendMethodId) {
        return methodMapper.selectList(new LambdaQueryWrapper<Method>()
                .eq(Method::getRecommendMethodId,recommendMethodId)
                .eq(Method::getIsDelete,BoolEnum.FALSE.getValue()));
    }

    @Override
    public PageVo<Method> getPublicMethodList(Boolean isOnStock, String namePrefix, Integer pageSize, Integer pageNum) {
        IPage<Method> page = new Page<>(pageNum,pageSize);
        LambdaQueryWrapper<Method> query = new LambdaQueryWrapper<>();
        query.isNull(Method::getUserId);
        if(!StringUtils.isEmpty(namePrefix)){
            query.likeRight(Method::getName,namePrefix);
        }
        if(isOnStock!=null){
            query.eq(Method::getOnStock,isOnStock?1:0);
        }
       IPage<Method> result= methodMapper.selectPage(page,query);
        return  new PageVo<Method>(result);
    }

	@Override
	public int getMethodCountByUserId(Long userId) {
		LambdaQueryWrapper<Method> query1 = new LambdaQueryWrapper<>();
        query1.eq(Method::getUserId, userId);
        query1.eq(Method::getCurrent, BoolEnum.TRUE.getValue());
        query1.eq(Method::getIsDelete, BoolEnum.FALSE.getValue());
        return methodMapper.selectCount(query1);
	}

    @Override
    public int getMethodCountByUserIdList(List<Long> ids) {
        LambdaQueryWrapper<Method> query1 = new LambdaQueryWrapper<>();
        query1.in(Method::getUserId, ids);
        query1.eq(Method::getCurrent, BoolEnum.TRUE.getValue());
        query1.eq(Method::getIsDelete, BoolEnum.FALSE.getValue());
        return methodMapper.selectCount(query1);
    }


    @Override
    public List<Method> selectCurrentListByMethodTypeIdsAndUserId(List<Long> thirdMethodTypeIds,Long userId,boolean hasCommonMethod) {
        if(!CollectionUtils.isEmpty(thirdMethodTypeIds)){
            return methodMapper.selectCurrentListByMethodTypeIdsAndUserId(thirdMethodTypeIds,userId,hasCommonMethod);
        }
        return new ArrayList<>(0);
    }

    @Override
    public int countCurrentListByMethodTypeIdsAndUserId(List<Long> methodTypeIds,Long userId,boolean hasCommonMethod) {
        if(!CollectionUtils.isEmpty(methodTypeIds)){
            return methodMapper.countCurrentListByMethodTypeIdsAndUserId(methodTypeIds,userId, hasCommonMethod);
        }
        return 0;
    }

    @Override
    public boolean resetToCurrent(Long userId, Long initMehtodId) {
        return methodMapper.resetToCurrent(userId,initMehtodId)>0;
    }

    @Override
    public List<Method> insertBatch(List<Method> methods) {
        if (!CollectionUtils.isEmpty(methods)){
            methodMapper.insertBatch(methods);
            return methods;
        }
        return new ArrayList<>(0);
    }

    @Override
    public int updateInitInfo(List<Method> methods) {
        if (!CollectionUtils.isEmpty(methods)){
            return methodMapper.updateInitInfo(methods);
        }
        return 0;
    }
}
